iT邦幫忙

2025 iThome 鐵人賽

DAY 17
1
Modern Web

Laravel 12 開發者幸福度升級指南系列 第 17

Day 17:pest 生成測試覆蓋率,設置最低覆蓋率

  • 分享至 

  • xImage
  •  

昨天我們提到了要減少線上錯誤,可以使用測試環境提前偵測錯誤,以及在遇到線上錯誤時使用維護頁面,提升使用者體驗。

今天我們繼續聊減少線上錯誤的方式

自動化測試

自動化測試是其中一個專案的保護機制,如果我們的應用沒有通過自動化測試的話,會在自動整合的階段失敗,阻止專案被部署到線上。

在開發時,我們已經透過 AI 幫我們加上了一些自動化測試,減少我們所產出的程式碼犯錯的機會。

不過,我們怎麼知道測試是否已經盡可能覆蓋到所有的狀況呢?

我們可以透過檢查自動化測試的測試覆蓋率,來協助確認這種狀況

安裝 xdebug

首先,我們先安裝 xdebug 幫助我們生成測試報告

pecl install xdebug

安裝套件之後,要在 php.ini 之內引入,首先我們找到 php.ini 的位置

php --ini

Configuration File (php.ini) Path: /usr/local/etc/php
Loaded Configuration File:         /Users/se07/.config/herd-lite/bin/php.ini

編輯一下 php.ini,打開 xdebug,加入

zend_extension=/opt/homebrew/lib/php/pecl/20240924/xdebug.so
xdebug.mode=coverage

加入之後,我們檢查一下是否安裝成功

php -v

Zend Engine v4.4.1, Copyright (c) Zend Technologies
    with Xdebug v3.4.5, Copyright (c) 2002-2025, by Derick Rethans

看到裡面有 Xdebug 的文字出現之後,我們就確定安裝成功了。

生成覆蓋率報告

接著,我們就可以開始生成報告了

我們所使用的測試框架 pest 依賴於 phpunit,所以我們會需要一個 phpunit.xml

很幸運的,Laravel 已經幫我們建立好這個檔案了。

所以我們可以直接用指令生成報告

php artisan test --coverage

如果所有測試順利通過,我們可以看到類似下面的報告

Tests:    47 passed (213 assertions)
  Duration: 6.76s

  Console/Commands/NewUserCommand ....................................... 0.0%
  Filament/Resources/Categories/CategoryResource .............. 27..32 / 80.0%
  Filament/Resources/Categories/Pages/CreateCategory .................. 100.0%
  Filament/Resources/Categories/Pages/EditCategory ...................... 0.0%
  Filament/Resources/Categories/Pages/ListCategories .................... 0.0%
  Filament/Resources/Categories/Schemas/CategoryForm .................... 0.0%
  Filament/Resources/Categories/Tables/CategoriesTable .................. 0.0%
  Filament/Resources/ProductImages/Pages/CreateProductImage ........... 100.0%
  Filament/Resources/ProductImages/Pages/EditProductImage ............... 0.0%
  Filament/Resources/ProductImages/Pages/ListProductImages .............. 0.0%
  Filament/Resources/ProductImages/Pages/ViewProductImage ............... 0.0%
  Filament/Resources/ProductImages/ProductImageResource ....... 29..39 / 75.0%
  Filament/Resources/ProductImages/Schemas/ProductImageForm ............. 0.0%
  Filament/Resources/ProductImages/Schemas/ProductImageInfolist ......... 0.0%
  Filament/Resources/ProductImages/Tables/ProductImagesTable ............ 0.0%
  Filament/Resources/Products/Pages/CreateProduct ..................... 100.0%
  Filament/Resources/Products/Pages/EditProduct ......................... 0.0%
  Filament/Resources/Products/Pages/ListProducts ........................ 0.0%
  Filament/Resources/Products/Pages/ViewProduct ......................... 0.0%
  Filament/Resources/Products/ProductResource ................. 29..39 / 75.0%
  Filament/Resources/Products/Schemas/ProductForm ....................... 0.0%
  Filament/Resources/Products/Schemas/ProductInfolist ................... 0.0%
  Filament/Resources/Products/Tables/ProductsTable ...................... 0.0%
  Http/Controllers/Auth/VerifyEmailController ......................... 100.0%
  Http/Controllers/CategoryController ..................... 32, 79, 85 / 92.5%
  Http/Controllers/Controller ......................................... 100.0%
  Http/Controllers/ProductController .................................. 100.0%
  Http/Controllers/ProductImageController ......... 28, 61..63, 80, 86 / 91.7%
  Http/Controllers/TagController ........................................ 0.0%
  Http/Requests/StoreCategoryRequest .................................. 100.0%
  Http/Requests/StoreProductImageRequest .............................. 100.0%
  Http/Requests/StoreProductRequest ................................... 100.0%
  Http/Requests/StoreTagRequest ......................................... 0.0%
  Http/Requests/UpdateCategoryRequest ................................. 100.0%
  Http/Requests/UpdateProductImageRequest ............................. 100.0%
  Http/Requests/UpdateProductRequest .................................. 100.0%
  Http/Requests/UpdateTagRequest ........................................ 0.0%
  Http/Resources/CategoryResource ..................................... 100.0%
  Http/Resources/ProductImageResource ................................. 100.0%
  Http/Resources/ProductResource ...................................... 100.0%
  Http/Resources/TagResource ............................................ 0.0%
  Livewire/Actions/Logout ............................................. 100.0%
  Models/Category ..................................................... 100.0%
  Models/Product ...................................................... 100.0%
  Models/ProductImage ................................................. 100.0%
  Models/User ......................................................... 100.0%
  Policies/ProductPolicy ................................................ 0.0%
  Providers/AppServiceProvider ........................................ 100.0%
  Providers/Filament/AdminPanelProvider ............................... 100.0%
  Providers/VoltServiceProvider ....................................... 100.0%
  ────────────────────────────────────────────────────────────────────────────
                                                                 Total: 45.3 %

這邊就可以看到整體的報告了!

如果想要更細緻的報告,我們可以生成網頁版的報告

php artisan test --coverage-html=coverage

這會建立一個資料夾 coverage,然後在裡面放入網頁版的報告。

我們可以從 coverage/index.html 開始,瀏覽每個資料夾,甚至每個 PHP 檔案的每一行,看看是否有被測試覆蓋到

coverage

這樣一來,我們就可以用比較直觀的方式,來看出我們哪些地方還沒有做自動化測試了

在自動整合階段檢查覆蓋率

能夠看到覆蓋率報告之後,我們可能會希望透過某種自動檢查的方式,在覆蓋率不夠的時候擋住。

這個也是可以達成的!

我們可以用 --min 參數,來設定可以允許的最低覆蓋率

php artisan test --coverage --min=80

 FAIL  Code coverage below expected: 45.4 %. Minimum: 80.0 %.

這時候我們會看到,由於我們專案的覆蓋率沒有通過允許的覆蓋率,所以這邊拋出了錯誤

如果要加在自動整合的流程裡面,我們可以編輯一下 .github/workflows/tests.ymlRun Tests

      - name: Run Tests
        run: ./vendor/bin/pest --coverage --min=80

加入之後,如果我們試著上傳到 GitHub,我們就會在自動整合階段由於覆蓋率不足,所以被阻止

CI Fail

這樣一來,我們就又多了一個安全機制,在加入功能但是自動化測試覆蓋率不足的時候,避免實際部署到線上了。

今天的部分就到這邊,我們明天見


上一篇
Day 16:藉由線上測試環境減少問題,進入維修畫面
下一篇
Day 18:Feature Flags、Laravel Pennant 和不同發布模式觀念
系列文
Laravel 12 開發者幸福度升級指南19
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言